//
//  NSObject+EX.m
//  EasyCar
//
//  Created by nsm on 2017/5/26.
//  Copyright © 2017年 beisheng. All rights reserved.
//

#import "NSObject+EX.h"
#import <objc/runtime.h>

@implementation NSObject (EX)
+ (BOOL)swizzleMethod:(SEL)originalSel withMethod:(SEL)newSel {
    Method ori_m = class_getInstanceMethod(self, originalSel);
    Method new_m = class_getInstanceMethod(self, newSel);
    if (!ori_m || !new_m) return NO;
    
    class_addMethod(self,
                    originalSel,
                    method_getImplementation(ori_m),
                    method_getTypeEncoding(ori_m));
    class_addMethod(self,
                    newSel,
                    method_getImplementation(new_m),
                    method_getTypeEncoding(new_m));
    method_exchangeImplementations(class_getInstanceMethod(self, originalSel),
                                   class_getInstanceMethod(self, newSel));
    
    return YES;
}

- (void)showAlert:(NSString *)message {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
                                                    message:message
                                                   delegate:nil
                                          cancelButtonTitle:@"确定"
                                          otherButtonTitles:nil, nil];
    
    [alert show];
}

@end


@implementation UIViewController (exchange)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self swizzleMethod:@selector(viewWillAppear:) withMethod:@selector(nsm_viewWillAppear:)];
        [self swizzleMethod:NSSelectorFromString(@"dealloc") withMethod:@selector(nsm_dealloc)];
    });
}

- (void)nsm_viewWillAppear:(BOOL)animated {
    NSString *name = NSStringFromClass(self.class);
#ifdef DEBUG
    NSLog(@"\n[调试数据]viewWillAppear:%@", name);
#endif
    
    [self nsm_viewWillAppear:animated];
}

- (void)nsm_dealloc {
    NSString *name = NSStringFromClass(self.class);
#ifdef DEBUG
    NSLog(@"\n[调试数据] dealloc:%@", name);
#endif
    
    [self nsm_dealloc];
}

- (void)showAlert:(NSString *)message action:(void (^)(UIAlertAction *))handler completion:(void (^)(void))completion {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示"
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *doneAction = [UIAlertAction actionWithTitle:@"确定" style:0 handler:handler];
    [alert addAction:doneAction];
    [self presentViewController:alert animated:YES completion:completion];
}

- (void)showAlert:(NSString *)message action:(void (^)(UIAlertAction *))handler {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示"
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *doneAction = [UIAlertAction actionWithTitle:@"确定" style:0 handler:handler];
    [alert addAction:doneAction];
    [self presentViewController:alert animated:YES completion:nil];
}

- (void)showAlert:(NSString *)message cancel:(void (^)(UIAlertAction *))cancel done:(void (^)(UIAlertAction *))done {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示"
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消"
                                                           style:0
                                                         handler:cancel];
    UIAlertAction *doneAction = [UIAlertAction actionWithTitle:@"确定"
                                                         style:0
                                                       handler:done];
    [alert addAction:cancelAction];
    [alert addAction:doneAction];
    [self presentViewController:alert animated:YES completion:nil];
}

- (void)showAlert:(NSString *)title message:(NSString *)message action:(void (^)(UIAlertAction *action))done {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *doneAction = [UIAlertAction actionWithTitle:@"确定"
                                                         style:0
                                                       handler:done];
    [alert addAction:doneAction];
    [self presentViewController:alert animated:YES completion:nil];
}

- (void)showAlert:(NSString *)title message:(NSString *)message cancel:(void (^)(UIAlertAction *))cancel done:(void (^)(UIAlertAction *))done {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title
                                                                   message:message
                                                            preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消"
                                                           style:0
                                                         handler:cancel];
    UIAlertAction *doneAction = [UIAlertAction actionWithTitle:@"确定"
                                                         style:0
                                                       handler:done];
    [alert addAction:cancelAction];
    [alert addAction:doneAction];
    [self presentViewController:alert animated:YES completion:nil];
}

@end

@implementation NSDictionary (EX)
- (NSString *)printString {
    if (!self.count) return nil;
    
    NSString *step1 = [self.description stringByReplacingOccurrencesOfString:@"\\u"
                                                                  withString:@"\\U"];
    NSString *step2 = [step1 stringByReplacingOccurrencesOfString:@"\""
                                                       withString:@"\\\""];
    NSString *step3 = [[@"\"" stringByAppendingString:step2] stringByAppendingString:@"\""];
    
    return [NSPropertyListSerialization propertyListWithData:[step3 dataUsingEncoding:NSUTF8StringEncoding]
                                                     options:0
                                                      format:NULL
                                                       error:NULL];
}
@end

@implementation UILabel (EX)
- (void)setTextAlignmentScaleToFill {
    if (!self.text) return;
    
    CGSize textSize = [self.text boundingRectWithSize:CGSizeMake(self.frame.size.width, MAXFLOAT)
                                          options:(NSStringDrawingUsesLineFragmentOrigin |
                                                   NSStringDrawingUsesFontLeading|
                                                   NSStringDrawingTruncatesLastVisibleLine)
                                       attributes:@{NSFontAttributeName: self.font}
                                          context:nil].size;
    CGFloat between = (self.frame.size.width-textSize.width) / MAX((self.text.length-1), 1);
    NSMutableAttributedString *attrM = [[NSMutableAttributedString alloc] initWithString:self.text];
    [attrM addAttributes:@{NSKernAttributeName: @(between)}
                   range:NSMakeRange(0, self.text.length-1)];
    self.attributedText = attrM;
}
@end

@implementation UIView (EX)
- (void)setCorners:(NSMViewCorner)corners radius:(CGFloat)radius {
    CGRect rect = self.bounds;
    CGFloat minx = CGRectGetMinX(rect);
    CGFloat midx = CGRectGetMidX(rect);
    CGFloat maxx = CGRectGetMaxX(rect);
    CGFloat miny = CGRectGetMinY(rect);
    CGFloat midy = CGRectGetMidY(rect);
    CGFloat maxy = CGRectGetMaxY(rect);
    
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, nil, minx, midy);
    CGPathAddArcToPoint(path, nil, minx, miny, midx, miny, (corners & NSMViewCornerUpperLeft) ? radius : 0);
    CGPathAddArcToPoint(path, nil, maxx, miny, maxx, midy, (corners & NSMViewCornerUpperRight) ? radius : 0);
    CGPathAddArcToPoint(path, nil, maxx, maxy, midx, maxy, (corners & NSMViewCornerLowerRight) ? radius : 0);
    CGPathAddArcToPoint(path, nil, minx, maxy, minx, midy, (corners & NSMViewCornerLowerLeft) ? radius : 0);
    CGPathCloseSubpath(path);
    
    CAShapeLayer *maskLayer = [CAShapeLayer new];
    maskLayer.path = path;
    self.layer.mask = nil;
    self.layer.mask = maskLayer;
    CFRelease(path);
}
@end

@implementation UIView (FullSnapshot)
- (UIImage *)fullSnapshot {
    /**
     UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
     size       区域大小
     opaque     是否非透明(YES:非透明 NO:半透明效果)
     scale      屏幕缩放比(UIScreen.mainScreen.scale)
     */
    UIImage *snapshotImage = nil;
    // 1.判断是否包含滚动视图
    BOOL scrollEnabled = NO;
    scrollEnabled = ([self isKindOfClass:WKWebView.class] ||
                     [self isKindOfClass:UITableView.class] ||
                     [self isKindOfClass:UICollectionView.class] ||
                     [self isKindOfClass:UIScrollView.class]);
    if (scrollEnabled) {
        UIScrollView *scrollView = nil;
        if ([self isKindOfClass:WKWebView.class])
            scrollView = ((WKWebView *)self).scrollView;
        else if ([self isKindOfClass:UITableView.class])
            scrollView = (UITableView *)self;
        else if ([self isKindOfClass:UICollectionView.class])
            scrollView = (UICollectionView *)self;
        else if ([self isKindOfClass:UIScrollView.class])
            scrollView = (UIScrollView *)self;
        
        if (!scrollView) return nil;
        
        // 记录原始值
        CGPoint oriOffset = scrollView.contentOffset;
        CGRect oriFrame = scrollView.frame;
        // 图片拉满
        CGSize size = scrollView.contentSize;
        scrollView.contentOffset = CGPointZero;
        scrollView.frame = CGRectMake(0, 0, size.width, size.height);
        // 截图
        UIGraphicsBeginImageContextWithOptions(size,
                                               self.opaque,
                                               UIScreen.mainScreen.scale);
        [self.layer renderInContext:UIGraphicsGetCurrentContext()];
        snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        // 恢复
        scrollView.contentOffset = oriOffset;
        scrollView.frame = oriFrame;
    } else {
        UIGraphicsBeginImageContextWithOptions(self.bounds.size,
                                               self.opaque,
                                               UIScreen.mainScreen.scale);
        [self.layer renderInContext:UIGraphicsGetCurrentContext()];
        snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    
    return snapshotImage;
}

@end

@implementation NSMButton (Ex)
+ (instancetype)buttonWithTitle:(NSString *)title target:(id)target action:(SEL)action {
    NSMButton *btn = [NSMButton new];
    btn.backgroundColor = THEME_COLOR;
    btn.myHeight = 48;
    btn.height = 48;
    btn.enabled = NO;
    btn.titleLabel.font = BoldSystemFont(18);
    [btn setTitle:title forState:UIControlStateNormal];
    [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
    ViewCorner(btn, 6);
    return btn;
}
@end

@implementation UIScrollView (CanScroll)
- (UIEdgeInsets)nsm_contentInset {
    if (@available(iOS 11, *)) {
        return self.adjustedContentInset;
    } else {
        return self.contentInset;
    }
}

- (BOOL)canScroll {
    if (CGSizeIsEmpty(self.bounds.size)) {
        return NO;
    }
    
    BOOL canVerticalScroll = (self.contentSize.height + UIEdgeInsetsGetHeight([self nsm_contentInset])) > self.height;
    BOOL canHorizontalScoll = (self.contentSize.width + UIEdgeInsetsGetWidth([self nsm_contentInset])) > self.width;
    return canVerticalScroll || canHorizontalScoll;
}
@end
